package com.ymttest.business.service.shenqi;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;

import com.shop2cn.iapi.sqoptrade.parameter.vo.*;
import org.apache.http.client.ClientProtocolException;
import org.joda.time.DateTime;

import com.google.common.collect.Lists;
import com.shop2cn.iapi.shenqisettlement.parameter.bean.AgentProductBean;
import com.shop2cn.iapi.sqoptrade.parameter.enums.AppTerminalSourceEnum;
import com.shop2cn.iapi.sqoptrade.parameter.enums.LogisticsTypeEnum;
import com.shop2cn.iapi.sqoptrade.parameter.enums.OrderSourceEnum;
import com.shop2cn.iapi.sqoptrade.parameter.enums.TerminalSourceEnum;
import com.shop2cn.iapi.sqoptrade.parameter.req.PayReq;
import com.shop2cn.iapi.sqoptrade.parameter.req.PlaceOrderReq;
import com.shop2cn.iapi.sqoptrade.resp.TradingServiceResp;
import com.shop2cn.iapi.sqoptrade.service.PayReqCall;
import com.ymt.base.YmatouEasyCall;
import com.ymt.core.tool.Logger;
import com.ymttest.business.service.AccountCallServiceV2;
import com.ymttest.business.service.SQPayGateWayCallService;
import com.ymttest.utils.TestDataManager;
import com.ymttest.utils.YMTDateUtil;

public class SqTradingBookingOrderCallService {
	
	private static PlaceOrderReq placeOrderReq = new PlaceOrderReq();
	
	/**
	 * 创建二次确认orderVo
	 * @param agentProductBean
	 * @param orderId
	 * @param bookingPlaceOrderReq
	 * @return
	 */
	public static OrderVo createSecondConfirmOrderVo(
			AgentProductBean agentProductBean, Long orderId, PlaceOrderReq bookingPlaceOrderReq) {

		OrderVo orderVo = SqTradingCallService.createOrderVo(Arrays
				.asList(agentProductBean));

		orderVo.setBookingConfirmOrder(true);
		orderVo.setOrderId(orderId);

		orderVo.setOrderItems(bookingPlaceOrderReq.getOrderGroups().get(0)
				.getOrders().get(0).getOrderItems());

		orderVo.setLogisticsType(LogisticsTypeEnum.Unknown);
		orderVo.setAutoCancelOrderHours(new BigDecimal("0.50"));

		return orderVo;
	}
	
	public static PlaceOrderReq sqSimplePlaceOrderReq(long userId,
			AgentProductBean productBean) {

		PlaceOrderReq req = new PlaceOrderReq();
		
		req.setAddressId(772208L);
		req.setRecvMobile("136" + TestDataManager.getRandomNum(8));
		req.setRecvName("testUser");
		req.setAppId("ymt autotest");
		req.setUserId(userId);

		req.setFromShenqi(true);

		req.setAddress("上海,静安,江场三路,市北高新");
		req.setPostCode("200000");

		req.setEquipmentId(TestDataManager.getRandomUUID().toString());
		req.setDeviceId(TestDataManager.getRandomUUID().toString());
		req.setSourceIp(TestDataManager.getRandomIp());

		req.setAppTerminalSource(AppTerminalSourceEnum.Phone);
		req.setOrderSource(OrderSourceEnum.Wechat);
		req.setTerminalSource(TerminalSourceEnum.Android);

		req.setMainOrderId(SqTradingCallService.genMainOrderId(req.getUserId()));

		OrderVo orderVo = new OrderVo();

		orderVo.setGoodsOwnerId(productBean.getGoodsOwnerId());
		orderVo.setShenqiLogisticsType(999);
		orderVo.setShenqiIdCardRequirement(2);
		orderVo.setLogisticsType(LogisticsTypeEnum.PackageDelivery);
		orderVo.setAutoCancelOrderHours(new BigDecimal("0.50"));

		// 一个商家一个订单一个商品
		OrderGroupVo groupVo1 = new OrderGroupVo();

		groupVo1.setSellerId(productBean.getSellerId());
		groupVo1.setSellerLoginId(productBean.getSellerLoginId());

		groupVo1.setSellerCoupon(null);

		groupVo1.setOrders(Lists.newArrayList(orderVo));

		req.setOrderGroups(Lists.newArrayList(groupVo1));

		req.setCurrencySymbol("¥");
		req.setPayChannelType(1);

		req.setOrderSource(OrderSourceEnum.Other);

		return req;
	}
	
	/**
	 * 预订订单下单请求
	 * @param productBean
	 */
	public static PlaceOrderReq placeBookingOrderReq(AgentProductBean productBean) {
		
		placeOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(4321,
				BigDecimal.ZERO, 20238699, productBean, productBean
						.getGoodsOwnerId().intValue(), false);

		placeOrderReq
				.getOrderGroups()
				.get(0)
				.getOrders()
				.get(0)
				.getOrderItems()
				.get(0)
				.setEarnestAmount(
						TestDataManager.randomPrice(BigDecimal.ZERO,
								BigDecimal.TEN));
		placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
				.getOrderItems().get(0)
				.setBookingPromotionAmount(new BigDecimal("20.00"));
		placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
				.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
		placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
				.setPaymentEndTime(DateTime.now().plusDays(2).toDate());
		
		return placeOrderReq;
	}
	
	/**
	 * 预订订单下单
	 * @param productBean
	 */
	public static TradingServiceResp placeBookingOrder(AgentProductBean productBean) {
		
		placeOrderReq = placeBookingOrderReq(productBean);
		
		placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
				.setEarnestDeliveryPromiseDays(1);
		
		return SqTradingCallService.callPlaceOrderService(placeOrderReq);
	}

	/**
	 * 创建一个预售活动订单
	 * @param productBean
	 * @return
	 * @throws Exception
	 */
	public static TradingServiceResp placePreSaleActivityBookingOrder(
			AgentProductBean productBean, int productNum) throws Exception {

		int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
				true, 10);

		placeOrderReq = placeBookingOrderReq(productBean);

		placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
				.setEarnestDeliveryPromiseDays(1);

		OrderVo orderVo = placeOrderReq.getOrderGroups().get(0).getOrders().get(0);
		OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

		ActivityVo activityVo = new ActivityVo();

		activityVo.setActivityId(activityId);
		activityVo.setActivityTemplateId(5123);
		activityVo.setAfterActivityFinishAccept(true);
		activityVo.setProductInActivityId(1234);

		orderItemVo.setProductNum(productNum);
		orderItemVo.setActivity(activityVo);

		return SqTradingCallService.callPlaceOrderService(placeOrderReq);
	}
	
	/**
	 * 组合商品预订订单下单
	 * @param productBean
	 */
	public static TradingServiceResp placeComposeProductBookingOrder(AgentProductBean productBean) {
		
		placeOrderReq = placeBookingOrderReq(productBean);
		
		placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
				.setEarnestDeliveryPromiseDays(1);
		
		OrderItemVo orderItemVo1 = placeOrderReq.getOrderGroups().get(0)
				.getOrders().get(0).getOrderItems().get(0);

		orderItemVo1.setProductPrice(new BigDecimal("1000.00"));
		orderItemVo1.setSubProduct(true);
		
		return SqTradingCallService.callPlaceOrderService(placeOrderReq);
	}
	
	/**
	 * 创建二次确认订单
	 * @param productBean
	 * @throws Exception 
	 */
	public static TradingServiceResp placeSecondConfirmOrder(
			AgentProductBean productBean) throws Exception {

		PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
				.placeBookingOrderReq(productBean);
		
		bookingPlaceOrderReq1.setUserId(26080783L);
		
		TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
				.callPlaceOrderService(bookingPlaceOrderReq1);

		long bookingOrderId = bookingPlaceOrderResp.getOrderList().get(0)
				.getOrderId();

		// 支付定金
		long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(
				bookingPlaceOrderReq1.getUserId(),
				bookingPlaceOrderResp.getTradingId());
		BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

		// 支付网关支付回调交易
		SQPayGateWayCallService.DGSQNotifyCall(String.valueOf(thirdTradingId),
				totalPrice.subtract(BigDecimal.ZERO).toString(),
				(int) bookingPlaceOrderReq1.getUserId(),
				BigDecimal.ZERO.toPlainString(), productBean.getCurrency());

		Thread.sleep(5000);

		// 创建一个二次确认订单
		placeOrderReq = SqTradingBookingOrderCallService.sqSimplePlaceOrderReq(
				bookingPlaceOrderResp.getUserId(), productBean);

		OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
				.createSecondConfirmOrderVo(productBean, bookingOrderId,
						bookingPlaceOrderReq1);
		
		OrderItemVo orderItemVo = secondConfirmOrderVo1.getOrderItems().get(0);
		
		// 设置税率
		orderItemVo.setSku("C052901");
		orderItemVo.setProductRecordNo("C052901");

		OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);

		groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1));

//		placeOrderReq.setIntegral(10L);
//		placeOrderReq.setIntegralServiceType(2);

		return SqTradingCallService.callPlaceOrderService(placeOrderReq);
	}
	
	public static TradingServiceResp placePickupStoreSecondConfirmOrder(
			AgentProductBean productBean) throws Exception {

		PlaceOrderReq bookingPlaceOrderReq1 = SqTradingBookingOrderCallService
				.placeBookingOrderReq(productBean);
		
		bookingPlaceOrderReq1.setUserId(26080783L);
		
		bookingPlaceOrderReq1.setPickupInStores(true);
		PickInStoreVo pickInStoreVo = new PickInStoreVo();

		pickInStoreVo.setPickupStoreId((long) TestDataManager
				.getRandomIntNum(6));
		pickInStoreVo.setPickupType(0);
		pickInStoreVo.setPickupUserName(TestDataManager.getChineseName());
		pickInStoreVo.setPickupUserPhone(TestDataManager.getPhoneNum());
		pickInStoreVo.setUserReserveTimeSpanStart(YMTDateUtil
				.getBeforeOrNextDate(0));
		pickInStoreVo.setUserReserveTimeSpanEnd(YMTDateUtil
				.getBeforeOrNextDate(10));

		bookingPlaceOrderReq1.setPickInStoreVo(pickInStoreVo);
		
		TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
				.callPlaceOrderService(bookingPlaceOrderReq1);

		long bookingOrderId = bookingPlaceOrderResp.getOrderList().get(0)
				.getOrderId();

		// 支付定金
		long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(
				bookingPlaceOrderReq1.getUserId(),
				bookingPlaceOrderResp.getTradingId());
		BigDecimal totalPrice = bookingPlaceOrderResp.getPayableAmount();

		// 支付网关支付回调交易
		SQPayGateWayCallService.DGSQNotifyCall(String.valueOf(thirdTradingId),
				totalPrice.subtract(BigDecimal.ZERO).toString(),
				(int) bookingPlaceOrderReq1.getUserId(),
				BigDecimal.ZERO.toPlainString(), productBean.getCurrency());

		Thread.sleep(5000);

		// 创建一个二次确认订单
		placeOrderReq = SqTradingBookingOrderCallService.sqSimplePlaceOrderReq(
				bookingPlaceOrderResp.getUserId(), productBean);

		OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
				.createSecondConfirmOrderVo(productBean, bookingOrderId,
						bookingPlaceOrderReq1);
		
		OrderItemVo orderItemVo = secondConfirmOrderVo1.getOrderItems().get(0);
		
		// 设置税率
		orderItemVo.setSku("C052901");
		orderItemVo.setProductRecordNo("C052901");

		OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);

		groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1));
		
		pickInStoreVo.setPickupStoreId((long) TestDataManager
				.getRandomIntNum(6));
		pickInStoreVo.setPickupType(0);
		pickInStoreVo.setPickupUserName(TestDataManager.getChineseName());
		pickInStoreVo.setPickupUserPhone(TestDataManager.getPhoneNum());
		pickInStoreVo.setUserReserveTimeSpanStart(YMTDateUtil
				.getBeforeOrNextDate(0));
		pickInStoreVo.setUserReserveTimeSpanEnd(YMTDateUtil
				.getBeforeOrNextDate(10));
		
		placeOrderReq.setPickInStoreVo(pickInStoreVo);
		placeOrderReq.setPickupInStores(true);

		return SqTradingCallService.callPlaceOrderService(placeOrderReq);
	}

	/**
	 * 创建一个预售活动未核销的二次确认订单
	 * @param productBean
	 * @return
	 * @throws Exception
	 */
	public static TradingServiceResp placePreSaleActivitySecondConfirmOrder(
			AgentProductBean productBean) throws Exception {

		int activityId = SqTradingProductService.agentProductAddPreSaleActivity(productBean,
				true, 10);

		PlaceOrderReq bookingPlaceOrderReq = SqTradingCallService.buildDGSQStandPlaceOrderReq(
				4321, BigDecimal.ZERO, 20238699, productBean,
				productBean.getGoodsOwnerId());

		OrderVo orderVo = bookingPlaceOrderReq.getOrderGroups().get(0).getOrders().get(0);
		OrderItemVo orderItemVo = orderVo.getOrderItems().get(0);

		ActivityVo activityVo = new ActivityVo();

		activityVo.setActivityId(activityId);
		activityVo.setActivityTemplateId(5123);
		activityVo.setAfterActivityFinishAccept(true);
		activityVo.setProductInActivityId(1234);

		orderItemVo.setProductNum(10);
		orderItemVo.setActivity(activityVo);
		orderItemVo.setEarnestAmount(BigDecimal.TEN);
		orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

		orderVo.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
		orderVo.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

		TradingServiceResp bookingPlaceOrderResp = SqTradingCallService
				.callPlaceOrderService(bookingPlaceOrderReq);

		Long userId = bookingPlaceOrderReq.getUserId();

		// 支付定金
		long thirdTradingId = SqTradingBookingOrderCallService.payBookingOrder(userId,
				bookingPlaceOrderResp.getTradingId());

		// 支付网关支付回调交易
		SQPayGateWayCallService.DGSQNotifyCall(
				String.valueOf(thirdTradingId),
				bookingPlaceOrderResp.getPayableAmount().subtract(BigDecimal.ZERO).toString(),
				userId.intValue(), BigDecimal.ZERO.toPlainString(),
				productBean.getCurrency());

		Thread.sleep(5000);

		// 创建一个二次确认订单
		placeOrderReq = SqTradingBookingOrderCallService.sqSimplePlaceOrderReq(
				bookingPlaceOrderResp.getUserId(), productBean);

		OrderVo secondConfirmOrderVo1 = SqTradingBookingOrderCallService
				.createSecondConfirmOrderVo(productBean, bookingPlaceOrderResp.getOrderList().get(0).getOrderId(),
						bookingPlaceOrderReq);

		OrderGroupVo groupVo = placeOrderReq.getOrderGroups().get(0);

		groupVo.setOrders(Arrays.asList(secondConfirmOrderVo1));

		return SqTradingCallService.callPlaceOrderService(placeOrderReq);
	}
	
	public static long payBookingOrder(long userId, long tradingId) {
		
		PayReq payReq = new PayReq();
		PayReqCall payReqCall = new PayReqCall();

		long thirdTradingId = 0;

		// 参数
		String tradingPassword = "abc123";
		payReq.setTradingId(tradingId);
		payReq.setUserId(userId);
		payReq.setTradingPwd(tradingPassword);
		payReq.setUserIp("103.84.20.0");
		payReq.setBankId("123");
		payReq.setPayType("6000");
		payReq.setTradeType(2);
		
		payReq.setOpenId(SQPayGateWayCallService.HipoPayWxAppOpenId);
		
		payReq.setParamExt("");
		payReq.setMemo("备注");
		payReq.setShenqiMpId("wxsqBuyer");
		payReq.setVoucherUrl("http://file.iapi.ymatou.com/G01/M00/1B/BB/rBBlD19Nw_qAEoieAAAKL_CeZ3Y268_65_14_o.png");

		payReqCall.setData(false, payReq);

		try {

			Logger.comment(String.format("用户  %s, 订单支付, 交易号 %s", userId,
					tradingId));
			
			if (payReq.getTradeType() == 2) {
				
				String accountid1 = AccountCallServiceV2.getAccountId((int) userId);
				AccountCallServiceV2.resetAccount(accountid1, new BigDecimal(
						9000000), new BigDecimal(0));
			}

			payReqCall.callService();

			thirdTradingId = payReqCall.getData().getLong("tradingId");
			Logger.comment(payReqCall.getData().optString("errorMessage"));

			if (payReqCall.getData().optString("errorMessage")
					.equalsIgnoreCase("账户金额不足")) {

				String accountid1 = AccountCallServiceV2
						.getAccountId((int) userId);
				AccountCallServiceV2.resetAccount(accountid1, new BigDecimal(
						9000000), new BigDecimal(0));

				thirdTradingId = payBookingOrder(userId, tradingId);
			} else if (payReqCall.getData().optString("errorMessage")
					.equalsIgnoreCase("订单支付收单超时")) {
				thirdTradingId = payBookingOrder(userId, tradingId);
			} else if (payReqCall.getData().optString("errorMessage")
					.equalsIgnoreCase("订单支付失败")) {
				thirdTradingId = payBookingOrder(userId, tradingId);
			}
		} catch (Exception e) {
			Logger.info(e.toString());
			Logger.info(String.format("########支付订单 交易号:%s 异常", tradingId));
		}
		
		return thirdTradingId;
	}
	
	public static long paySecondConfirmOrder(long userId, long tradingId) {
		
		PayReq payReq = new PayReq();
		PayReqCall payReqCall = new PayReqCall();

		long thirdTradingId = 0;

		// 参数
		String tradingPassword = "abc123";
		payReq.setTradingId(tradingId);
		payReq.setUserId(userId);
		payReq.setTradingPwd(tradingPassword);
		payReq.setUserIp("103.84.20.0");
		payReq.setBankId("123");
		payReq.setPayType("6000");
		payReq.setTradeType(1);
		
		payReq.setOpenId(SQPayGateWayCallService.HipoPayWxAppOpenId);
		
		payReq.setParamExt("");
		payReq.setMemo("备注");
		payReq.setShenqiMpId("wxsqBuyer");
		payReq.setVoucherUrl("http://file.iapi.ymatou.com/G01/M00/1B/BB/rBBlD19Nw_qAEoieAAAKL_CeZ3Y268_65_14_o.png");

		payReqCall.setData(false, payReq);

		try {

			Logger.comment(String.format("用户  %s, 订单支付, 交易号 %s", userId,
					tradingId));
			
			if (payReq.getTradeType() == 2) {
				
				String accountid1 = AccountCallServiceV2.getAccountId((int) userId);
				AccountCallServiceV2.resetAccount(accountid1, new BigDecimal(
						9000000), new BigDecimal(0));
			}

			payReqCall.callService();

			thirdTradingId = payReqCall.getData().getLong("tradingId");
			Logger.comment(payReqCall.getData().optString("errorMessage"));

			if (payReqCall.getData().optString("errorMessage")
					.equalsIgnoreCase("账户金额不足")) {

				String accountid1 = AccountCallServiceV2
						.getAccountId((int) userId);
				AccountCallServiceV2.resetAccount(accountid1, new BigDecimal(
						9000000), new BigDecimal(0));

				thirdTradingId = payBookingOrder(userId, tradingId);
			} else if (payReqCall.getData().optString("errorMessage")
					.equalsIgnoreCase("订单支付收单超时")) {
				thirdTradingId = payBookingOrder(userId, tradingId);
			} else if (payReqCall.getData().optString("errorMessage")
					.equalsIgnoreCase("订单支付失败")) {
				thirdTradingId = payBookingOrder(userId, tradingId);
			}
		} catch (Exception e) {
			Logger.info(e.toString());
			Logger.info(String.format("########支付订单 交易号:%s 异常", tradingId));
		}
		
		return thirdTradingId;
	}
	
	/**
	 * 二次确认订单自动取消
	 * @param bookingOrderId
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static void bookingOrderUnPaidFullAmountAutoCancel(long bookingOrderId)
			throws ClientProtocolException, IOException {

		String orderJson = "{\"cancelReason\":\"自动化测试取消订单\",\"cancelType\":\"10\",\"orderId\":"
				+ bookingOrderId
				+ ",\"userId\":"
				+ placeOrderReq.getUserId()
				+ "}";
		
		// 发送请求
		YmatouEasyCall autoCancelOrderCall = new YmatouEasyCall("", "POST",
				"JSON");
		autoCancelOrderCall
				.setUrl("http://sqoptrade.iapi.shop2cn.com/api/Buyer/bookingOrderUnPaidFullAmountAutoCancel");
		
		autoCancelOrderCall.setData(orderJson);
		autoCancelOrderCall.callService();
	}
	
	/**
	 * 待二次确认订单，超过paymentEndTime，自动取消
	 * @param bookingOrderId
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static void bookingOrderUserViolationAutoCancel(long bookingOrderId)
			throws ClientProtocolException, IOException {

		String orderJson = "{\"orderId\":"
				+ bookingOrderId
				+ "}";
		
		// 发送请求
		YmatouEasyCall autoCancelOrderCall = new YmatouEasyCall("", "POST",
				"JSON");
		autoCancelOrderCall
				.setUrl("http://sqoptrade.iapi.shop2cn.com/api/Buyer/bookingOrderUserViolationAutoCancel");
		
		autoCancelOrderCall.setData(orderJson);
		autoCancelOrderCall.callService();
	}
 }
